import jwt
from passlib.context import CryptContext
from datetime import datetime, timedelta
from typing import Optional
from dotenv import load_dotenv
import os


class AuthHandler:
    def __init__(self):
        self.pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
        load_dotenv()
        self.secret_key = os.environ.get("JWT_SECRET_KEY")
        self.algorithm = "HS256"
        self.access_token_expire_minutes = 30  # token过期时间（分钟）

    def verify_password(self, plain_password, hashed_password):
        return self.pwd_context.verify(plain_password, hashed_password)

    def get_password_hash(self, password):
        return self.pwd_context.hash(password)

    def create_access_token(self, data: dict, expires_delta: Optional[int] = None):
        to_encode = data.copy()
        if expires_delta:
            expire = datetime.utcnow() + timedelta(hours=expires_delta)
        else:
            expire = datetime.utcnow() + timedelta(hours=24)
        to_encode.update({"exp": int(expire.timestamp())})
        for key, value in to_encode.items():
            if isinstance(value, datetime):
                to_encode[key] = value.strftime('%Y-%m-%d %H:%M:%S')
        encoded_jwt = jwt.encode(to_encode, self.secret_key, algorithm=self.algorithm)
        return encoded_jwt

    def decode_token(self, token):
        try:
            decoded_token = jwt.decode(token, self.secret_key, algorithms=[self.algorithm])
            return decoded_token if decoded_token["exp"] >= datetime.utcnow().timestamp() else None
        except jwt.ExpiredSignatureError:
            print("Token has expired (caught by exception)")
            return None
        except jwt.PyJWTError as e:
            print(f"An error occurred while decoding token: {e}")
            return None
